package com.sugon.controller.spare;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.annotation.AutoLog;
import com.sugon.annotation.LimitSubmit;
import com.sugon.annotation.NonBusinessParamValid;
import com.sugon.dao.SparePartKeyDao;
import com.sugon.dao.SparePartReplaceRecordDao;
import com.sugon.entity.*;
import com.sugon.entity.vo.AddKeySparePartParam;
import com.sugon.modules.sparepart.consts.SpPlanAbcEnum;
import com.sugon.service.*;
import com.sugon.utils.PageUtils;
import com.sugon.utils.Query;
import com.sugon.utils.R;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @Description: 关键零部件
 * @author: YuXD
 * @since: 2022-10-08
 * @Version: V1.0
 */
@Api(tags = "关键零部件")
@RestController
@RequestMapping("/sparePartKey")
@Slf4j
public class SparePartKeyController {
    @Resource
    private SparePartKeyService sparePartKeyService;
    @Resource
    private SparePartKeyDao sparePartKeyDao;
    @Resource
    private DeviceInfoService deviceInfoService;
    @Resource
    private SparePartService sparePartService;
    @Resource
    private SparePartConsumRecordService sparePartConsumRecordService;
    @Resource
    private DevRepairRecordService devRepairRecordService;
    @Resource
    private SparePartReplaceRecordService replaceRecordService;
    @Resource
    private SparePartReplaceRecordDao sparePartReplaceRecordDao;

    /**
     * 获取这个设备是否已建立这个关键备件
     */
    @RequestMapping("/loadKeySparePart")
    @ResponseBody
    public R loadCjKeySp(@RequestParam Map<String, Object> param) {
        param.put("delFlag", 1);
        Query query = new Query(param);
        List<SparePartKeyCj> posList = sparePartKeyService.queryCjKeySpList(null, MapUtil.getStr(param, "pareId"), MapUtil.getStr(param, "devId"), null);
        PageUtils pageUtil = new PageUtils(posList, posList.size(), query.getLimit(), query.getPage());
        return R.ok().put("page", pageUtil);
    }

    /**
     * 获取这个设备是否已建立这个关键备件
     */
    @RequestMapping("/loadCjKeySpList")
    @ResponseBody
    public R loadCjKeySpList(@RequestParam Map<String, Object> param) {
        return R.ok().put("list", sparePartKeyService.queryCjKeySpList(null, MapUtil.getStr(param, "pareId"), MapUtil.getStr(param, "devId"), null));
    }

    @LimitSubmit(key = "addKeySparePart:%s")
    @NonBusinessParamValid
    @AutoLog("添加关键备件")
    @RequestMapping("/addKeySparePart")
    @ResponseBody
    public R addKeySparePart(@RequestBody AddKeySparePartParam param, BindingResult bindingResult) {
        // 校验设备维修记录是否存在
        DevRepairRecordEntity devRepairRecord = devRepairRecordService.queryObject(param.getRepairRecordId());
        if (devRepairRecord == null) {
            return R.error("设备维修记录不存在，请确认！");
        }
        // 请
        if(devRepairRecord.getRepairEndDate() == null){
            return R.error("请等待维");
        }
        // 校验备件换件记录是否存在
        SparePartConsumRecordEntity consumeRecord = sparePartConsumRecordService.queryObject(param.getSparePartConsumeRecordId());
        if (consumeRecord == null) {
            return R.error("备件换件记录不存在，请确认！");
        }
        // 禁止将消耗类备件添加为关键备件
        SparePartEntity sp = sparePartService.queryObject(consumeRecord.getSparePartId());
        Assert.notNull(sp, "备件不存在，备件ID：" + consumeRecord.getSparePartId());
        // C-消类型的备件不允许添加为关键备件
        if (StrUtil.equals(SpPlanAbcEnum.CONSUME.getValue(), sp.getPlanAbc())) {
            return R.error("消耗类备件不能设置为关键备件！");
        }
        // 一个维修换件记录只可以添加关键备件一次
        SparePartReplaceRecord existedReplaceRecord = sparePartReplaceRecordDao.queryByConsumeRecordId(param.getSparePartConsumeRecordId());
        if (existedReplaceRecord != null) {
            return R.error("已添加为关键备件，请勿重复添加！");
        }
        DeviceInfoEntity device = deviceInfoService.queryObject(devRepairRecord.getDevId());
        Assert.notNull(device);
        /*
            当从维修工单换件记录中添加关键备件时，目前来说
            只要不是C-消类型的备件都可以添加到系统中
         */
        SparePartKey sparePartKey = sparePartKeyService.checkKeySparePart(sp);
        /*
            校验这台设备(特定安装部位)下是否包含这个关键备件的实际记录
            如果没有则新增
            如果有，则完善老的，记录新的
         */
        List<SparePartKeyCj> cjKeySpList = sparePartKeyService.queryCjKeySpList(sparePartKey.getId(), null, devRepairRecord.getDevId(), param.getPosition());
        if (CollectionUtil.isEmpty(cjKeySpList)) {
            SparePartKeyCj ckKeySp = new SparePartKeyCj();
            ckKeySp.setKeySpId(sparePartKey.getId());
            ckKeySp.setSpId(sparePartKey.getSpareId());
            ckKeySp.setWorkshop(device.getWorkshopOrgId());
            ckKeySp.setDevId(devRepairRecord.getDevId());
            ckKeySp.setPosition(param.getPosition());
            // 默认按照天进行寿命计算
            ckKeySp.setComputeLifeWay("1");
            ckKeySp.setActualLife(0L);
            ckKeySp.setLastReplaceTime(devRepairRecord.getRepairEndDate());
            // 保存关键备件信息
            if (sparePartKeyService.save(ckKeySp)) {
                // 保存备件换件记录
                SparePartReplaceRecord replaceRecord = new SparePartReplaceRecord();
                replaceRecord.setSparePartKeyId(ckKeySp.getId());
                replaceRecord.setReplaceTime(devRepairRecord.getRepairEndDate());
                replaceRecord.setConsumeRecordId(param.getSparePartConsumeRecordId());
                replaceRecordService.save(replaceRecord);
            }
        } else {
            // 理论上：设备+安装部位+备件 唯一
            SparePartKeyCj cjKeySp = cjKeySpList.get(0);
            /*
                找到某条正在使用中的关键备件记录
                如果存在，则完善老的，生成新的
                如果不存在，则新增
             */
            SparePartReplaceRecord replaceRecord = replaceRecordService.findOngoingReplaceRecord(cjKeySp.getId());
            if (replaceRecord != null) {
                replaceRecord.setRetireTime(devRepairRecord.getRepairEndDate());
                replaceRecord.setLife(DateUtil.betweenDay(replaceRecord.getReplaceTime(), replaceRecord.getRetireTime(), true));
                if (replaceRecordService.update(replaceRecord)) {
                    // 重新计算下这个关键备件的平均寿命、最近一次更换时间
                    sparePartKeyDao.recomputeAvgLife(cjKeySp.getId(), DateUtil.formatDateTime(devRepairRecord.getRepairEndDate()));
                }
            }
            // 保存备件换件记录
            replaceRecord = new SparePartReplaceRecord();
            replaceRecord.setSparePartKeyId(cjKeySp.getId());
            replaceRecord.setReplaceTime(devRepairRecord.getRepairEndDate());
            replaceRecord.setConsumeRecordId(param.getSparePartConsumeRecordId());
            replaceRecordService.save(replaceRecord);
        }
        return R.ok("添加关键备件成功！");
    }

}
